﻿using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AspNetCoreMini;
using Newtonsoft.Json;

namespace TestMini
{
    public class Program
    {
        public static Task Main()
        {
            return new WebHostBuilder()
                .UseHttpListener("http://127.0.0.1:2337/")
                .Configure(app => app
                    //.Use(GetMiddleware)
                    //.Use(PostMiddleware)
                    //.Use(FooMiddleware)
                    .Use(TimeMiddleware)
                //.Use(ThreadMiddleware)
                )
                .Build()
                .StartAsync();
        }

        public static RequestDelegate GetMiddleware(RequestDelegate next)
        {
            return async context =>
            {
                if(context.Request.Method.Equals("get", StringComparison.OrdinalIgnoreCase))
                {
                    await context.Response.WriteAsync("[get]" + Environment.NewLine);
                }

                if(next != null)
                {
                    await next(context);
                }
            };
        }

        public static RequestDelegate PostMiddleware(RequestDelegate next)
        {
            return async context =>
            {
                if(context.Request.Method.Equals("post", StringComparison.OrdinalIgnoreCase))
                {
                    await context.Response.WriteAsync("[post]" + Environment.NewLine);
                    if(context.Request.Headers["Content-Type"] == "application/json")
                    {
                        System.IO.StreamReader reader = new System.IO.StreamReader(context.Request.Body, context.Request.ContentEncoding);
                        string stri = reader.ReadToEnd();
                        await context.Response.WriteAsync(stri + Environment.NewLine);
                        var json = JsonConvert.DeserializeObject<dynamic>(stri);
                    }
                }
                if(next != null)
                {
                    await next(context);
                }
            };
        }

        public static RequestDelegate FooMiddleware(RequestDelegate next)
        {
            return async context =>
            {
                await context.Response.WriteAsync("[ResponseBody]" + Environment.NewLine);
                if(next != null)
                {
                    await next(context);
                }
            };
        }

        public static RequestDelegate TimeMiddleware(RequestDelegate next)
        {
            return async context =>
            {
                var id = Guid.NewGuid().ToString("N");
                Console.WriteLine($"{id}--begin--{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}");
                Thread.Sleep(5000);
                Console.WriteLine($"{id}---end---{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}");
                await context.Response.WriteAsync("[Time:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "]" + Environment.NewLine);
                if(next != null)
                {
                    await next(context);
                }
            };
        }

        public static RequestDelegate ThreadMiddleware(RequestDelegate next)
        {
            return async context =>
            {
                context.Response.Headers.Add("Content-Type", "text/html;charset=utf-8");
                var url = context.Request.Url.ToString();
                var query = context.Request.Url.Query.Trim('?', '&');
                var qs = query.Split('&', StringSplitOptions.RemoveEmptyEntries).Select(x => x.Split('=')).ToDictionary(x => x[0], x => x[1]);
                qs.TryGetValue("salt", out string salt);
                qs.TryGetValue("hostName", out string hostName);
                qs.TryGetValue("userName", out string userName);
                qs.TryGetValue("machineId", out string machineId);
                qs.TryGetValue("clientVersion", out string clientVersion);
                qs.TryGetValue("buildNumber", out string buildNumber);
                if(url.Contains("rpc/ping.action"))
                {
                    await context.Response.WriteAsync(
                        $"<!-- af8cac3071956a280aee121b8f3862eb08cf749c68c483bc97135634b9df2466e9280ac9889d2d1746b635ef7901ed83c78948b612acc2ffaeb8c48e8b558324 -->\r\n<PingResponse><message></message><responseCode>OK</responseCode><salt>{salt}</salt></PingResponse>");
                }
                else if(url.Contains("rpc/obtainTicket.action"))
                {
                    qs.TryGetValue("buildDate", out string buildDate);
                    qs.TryGetValue("version", out string version);
                    qs.TryGetValue("versionNumber", out string versionNumber);
                    qs.TryGetValue("edition", out string edition);
                    qs.TryGetValue("productFamilyId", out string productFamilyId);
                    await context.Response.WriteAsync(
                        $"<!-- b4a874fd28dbbd9481c6e7150aafaa55ca814d73119b57c1f6259e9fd9d909960ca28d64b22f307aedfb3a0e28d2eb2c30205c08710104e32ee12cacef8a6d96 -->\r\n<ObtainTicketResponse><message>Buy this software if you like it!</message><prolongationPeriod>9223372036854775807</prolongationPeriod><responseCode>OK</responseCode><salt>{salt}</salt><ticketId>052304</ticketId><ticketProperties>	licensee={userName}	licenseType=0</ticketProperties></ObtainTicketResponse>");
                }

                if(next != null)
                {
                    await next(context);
                }
            };
        }
    }
}
